package org.jeecg.modules.workorder.controller;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.aspect.annotation.PermissionData;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.cusorder.entity.CusOrderInfo;
import org.jeecg.modules.cusorder.mapper.CusOrderInfoMapper;
import org.jeecg.modules.cusorder.service.ICusOrderInfoService;
import org.jeecg.modules.cusstyle.entity.CusStyleInfo;
import org.jeecg.modules.cusstyle.service.ICusStyleInfoService;
import org.jeecg.modules.manage.entity.SysConfig;
import org.jeecg.modules.manage.service.ISysConfigService;
import org.jeecg.modules.system.controller.SysAnnouncementController;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.workorder.entity.WorkingOrder;
import org.jeecg.modules.workorder.entity.WorkingOrderRecord;
import org.jeecg.modules.workorder.mapper.WorkingOrderMapper;
import org.jeecg.modules.workorder.service.IWorkingOrderRecordService;
import org.jeecg.modules.workorder.service.IWorkingOrderService;
import org.jeecg.modules.workorder.vo.OpenBomVO;
import org.jeecg.modules.workorder.vo.OpenWorkingOrderFormVO;
import org.jeecg.modules.workorder.vo.OpenWorkingOrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

 /**
 * @Description: 生产跟单
 * @Date:   2021-09-09
 * @Version: V1.0
 */
@Api(tags="生产跟单")
@RestController
@RequestMapping("/workingOrder")
@Slf4j
public class WorkingOrderController extends JeecgController<WorkingOrder, IWorkingOrderService>{
	
	public final Integer WORKDER_ORDER_CONFIRM_MODE = 2;//1=员工刷卡确认 2=批量扫码确认
	
	@Autowired
	private ISysUserService sysUserService;
	
	@Autowired
	private IWorkingOrderService workingOrderService;
	
	@Autowired
	private IWorkingOrderRecordService workingOrderRecordService;
	
	@Autowired
	private ICusStyleInfoService cusStyleInfoService;
	
	@Autowired
	private ICusOrderInfoService cusOrderInfoService;
	
	@Autowired
	private CusOrderInfoMapper cusOrderInfoMapper;
	
	@Autowired
	private WorkingOrderMapper workingOrderMapper;
	
	@Autowired
	private ISysDepartService sysDepartService;
	
	@Autowired
    private ISysConfigService sysConfigService;
	
	
	
	/**
	 * 生产跟单-分页列表查询
	 *
	 * @param productionOrderInfo
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@AutoLog(value = "生产跟单-分页列表查询")
	@ApiOperation(value="生产跟单-分页列表查询", notes="生产跟单-分页列表查询")
	@GetMapping(value = "/rootList")
	@PermissionData(pageComponent="prodOrder/ProductionOrderTrack")
	public Result<?> queryPageList(WorkingOrder workingOrder,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		String hasQuery = req.getParameter("hasQuery");
		LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if(hasQuery != null && "true".equals(hasQuery)){
            QueryWrapper<WorkingOrder> queryWrapper =  QueryGenerator.initQueryWrapper(workingOrder, req.getParameterMap());
            //queryWrapper.ge("store_status", 1);
            queryWrapper.eq("is_merged", 0);//被合并的工单不再显示
            queryWrapper.eq("store_by", loginUser.getUsername());//当前登录用户
            List<WorkingOrder> list = workingOrderService.queryTreeListNoPage(queryWrapper);
            IPage<WorkingOrder> pageList = new Page<>(1, 20, list.size());
            pageList.setRecords(list);
            return Result.OK(pageList);
        }else{
            String parentId = workingOrder.getPid();
            if (oConvertUtils.isEmpty(parentId)) {
                parentId = "0";
            }
            workingOrder.setPid(null);
            QueryWrapper<WorkingOrder> queryWrapper = QueryGenerator.initQueryWrapper(workingOrder, req.getParameterMap());
            // 使用 eq 防止模糊查询
            //queryWrapper.eq("a.pid", parentId);
            //queryWrapper.ge("store_status", 1);
            queryWrapper.eq("is_merged", 0);//被合并的工单不再显示
            queryWrapper.eq("store_by", loginUser.getUsername());//当前登录用户
            Page<WorkingOrder> page = new Page<WorkingOrder>(pageNo, pageSize);
            IPage<WorkingOrder> pageList = workingOrderService.page(page, queryWrapper);
            return Result.OK(pageList);
        }
	}

	 /**
      * 获取子数据
      * @param productionOrderInfo
      * @param req
      * @return
      */
	@AutoLog(value = "生产工单-获取子数据")
	@ApiOperation(value="生产工单-获取子数据", notes="生产工单-获取子数据")
	@GetMapping(value = "/childList")
	public Result<?> queryPageList(WorkingOrder workingOrder,HttpServletRequest req) {
		QueryWrapper<WorkingOrder> queryWrapper = QueryGenerator.initQueryWrapper(workingOrder, req.getParameterMap());
		LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		queryWrapper.ge("a.store_status", 1);
		queryWrapper.eq("a.is_merged", 0);//被合并的工单不再显示
        queryWrapper.eq("a.store_by", loginUser.getUsername());//当前登录用户
		Page<WorkingOrder> page = new Page<WorkingOrder>(1, 20);
        IPage<WorkingOrder> pageList = workingOrderService.page(page, queryWrapper);
		return Result.OK(pageList);
	}

    /**
      * 批量查询子节点
      * @param parentIds 父ID（多个采用半角逗号分割）
      * @return 返回 IPage
      * @param parentIds
      * @return
      */
	@AutoLog(value = "生产工单-批量获取子数据")
    @ApiOperation(value="生产工单-批量获取子数据", notes="生产工单-批量获取子数据")
    @GetMapping("/getChildListBatch")
    public Result<?> getChildListBatch(@RequestParam("parentIds") String parentIds) {
        try {
        	LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            QueryWrapper<WorkingOrder> queryWrapper = new QueryWrapper<>();
            List<String> parentIdList = Arrays.asList(parentIds.split(","));
            //queryWrapper.in("pid", parentIdList);
            queryWrapper.ge("a.store_status", 1);
            queryWrapper.eq("is_merged", 0);//被合并的工单不再显示
            queryWrapper.eq("store_by", loginUser.getUsername());//当前登录用户
            Page<WorkingOrder> page = new Page<WorkingOrder>(1, 20);
            IPage<WorkingOrder> pageList = workingOrderService.page(page, queryWrapper);
            return Result.OK(pageList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("批量查询子节点失败：" + e.getMessage());
        }
    }
	
	/**
	 *   添加
	 *
	 * @param productionOrderInfo
	 * @return
	 */
	@AutoLog(value = "生产工单-添加")
	@ApiOperation(value="生产工单-添加", notes="生产工单-添加")
	@PostMapping(value = "/add")
	public Result<?> add(@RequestBody WorkingOrder workingOrder) {
		workingOrderService.addWorkingOrder(workingOrder);
		return Result.OK("添加成功！");
	}
	
	/**
	 *  编辑
	 *
	 * @param productionOrderInfo
	 * @return
	 */
	@AutoLog(value = "生产工单-编辑")
	@ApiOperation(value="生产工单-编辑", notes="生产工单-编辑")
	@PutMapping(value = "/edit")
	public Result<?> edit(@RequestBody WorkingOrder workingOrder) {
		workingOrderService.updateWorkingOrder(workingOrder);
		return Result.OK("编辑成功!");
	}
	
	
	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "生产工单-通过id删除")
	@ApiOperation(value="生产工单-通过id删除", notes="生产工单-通过id删除")
	@DeleteMapping(value = "/delete")
	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
		workingOrderService.deleteWorkingOrder(id);
		return Result.OK("删除成功!");
	}
	
	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "生产工单-批量删除")
	@ApiOperation(value="生产工单-批量删除", notes="生产工单-批量删除")
	@DeleteMapping(value = "/deleteBatch")
	public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.workingOrderService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.OK("批量删除成功！");
	}
	
	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "生产工单-通过id查询")
	@ApiOperation(value="生产工单-通过id查询", notes="生产工单-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
		WorkingOrder workingOrder = workingOrderService.getById(id);
		if(workingOrder == null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(workingOrder);
	}
	
	/**
	 * 通过workNum查询
	 *
	 * @param workNum
	 * @return
	 */
	@AutoLog(value = "生产工单-通过工单号查询")
	@ApiOperation(value="生产工单-通过工单号查询", notes="生产工单-通过工单号查询")
	@GetMapping(value = "/queryByWorknum")
	public Result<?> queryByWorknum(@RequestParam(name="workNum",required=true) String workNum) {
		Map<String,String> map = workingOrderService.queryByWorknum(workNum);
		if(map == null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(map);
	}
	
	
	/**
	 * 通过订单id查询拟生成的开单单列表
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "生产工单-通过订单id查询拟生成的开单单列表")
	@ApiOperation(value="生产工单-通过订单id查询拟生成的开单单列表", notes="生产工单-通过订单id查询拟生成的开单单列表")
	@GetMapping(value = "/queryOpenListByOrderId")
	public Result<?> queryOpenListByOrderId(@RequestParam(name="orderId",required=true) String orderId, @RequestParam(name="styleId",required=false) String styleId) {
		List<OpenWorkingOrderVO> openList = workingOrderService.queryOpenListByOrderId(orderId,styleId);
		if(openList == null || openList.size() == 0) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(openList);
	}
	
	/**
	 * 通过订单id和款式id查询物料列表
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "生产工单-通过订单id和款式id查询物料列表")
	@ApiOperation(value="生产工单-通过订单id和款式id查询物料列表", notes="生产工单-通过订单id和款式id查询物料列表")
	@GetMapping(value = "/queryBomListByOrderId")
	public Result<?> queryBomListByOrderId(@RequestParam(name="orderId",required=true) String orderId,@RequestParam(name="styleId",required=false) String styleId) {
		List<OpenBomVO> openList = workingOrderService.queryBomListByOrderId(orderId,styleId);
		if(openList == null || openList.size() == 0) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(openList);
	}
	

	
	/**
	 * 开单操作
	 * @param OpenProdOrderVO
	 * @return
	 */
	@AutoLog(value = "生产工单-开单")
	@ApiOperation(value="生产工单-开单", notes="生产工单-开单")
	@PostMapping(value = "/openWorkOrder")
	@Transactional
	public Result<?> openWorkOrder(@RequestBody OpenWorkingOrderFormVO formVO) {
		LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		String sendBy = "";//发送人
		String sendDept = "";//发送部门
		String receiveBy = "";//接收人
		String receiveDept = "";//接收部门
		String storeBy = "";//存货人
		String storeDept = "";//存货部门
		// 判断是否由系统自动生产开单
		SysConfig sysConfig = sysConfigService.getOne(null);
		if (sysConfig == null || sysConfig.getIsAutoOpenWorkorder() == null) {
			return Result.error("未找到对应的参数配置");
		} else if(sysConfig.getIsAutoOpenWorkorder() == 1 && sysConfig.getDefaultStoreBy() == null) {
			return Result.error("当前为自动生产开单模式，请设置开单默认存货人！");
		}
		if (sysConfig.getIsAutoOpenWorkorder() == 1) {//审完订单自动生产开单
			SysUser user = sysUserService.getUserByName(sysConfig.getDefaultStoreBy());
			sendBy = loginUser.getUsername();//发送人
			sendDept = loginUser.getOrgCode();//发送部门
			receiveBy = user.getUsername();//接收人
			receiveDept = user.getOrgCode();//接收部门
			storeBy = user.getUsername();//存货人
			storeDept = user.getOrgCode();//存货部门
		} else {
			sendBy = loginUser.getUsername();//发送人
			sendDept = loginUser.getOrgCode();//发送部门
			receiveBy = loginUser.getUsername();//接收人
			receiveDept = loginUser.getOrgCode();//接收部门
			storeBy = loginUser.getUsername();//存货人
			storeDept = loginUser.getOrgCode();//存货部门
		}
		Date nowTime = new Date();
		String orderInfoId = formVO.getId();//订单ID
		List<OpenWorkingOrderVO> list = formVO.getOpenList();
		boolean isSuc = false;
		if(list != null && list.size() > 0) {
			for(OpenWorkingOrderVO vo : list) {
				String pn = vo.getPn();//拆分序号
				String workNum = String.valueOf(FillRuleUtil.executeRule("work_num_code",null));//工单号
				WorkingOrder workingOrder = new WorkingOrder();
				CusStyleInfo cusStyleInfo = this.cusStyleInfoService.getById(vo.getCusStyleId());
				workingOrder.setPn(pn);//拆分页
				workingOrder.setWorkNum(workNum);//工单号
				workingOrder.setStyleCodeNum(cusStyleInfo.getCodeNum());//款号
				workingOrder.setStyleImageString(cusStyleInfo.getStyleImageString());//图片
				workingOrder.setOrderInfoId(orderInfoId);//订单ID
				workingOrder.setStyleCusInfoId(vo.getCusStyleId());//款式ID
				workingOrder.setWorkOrderType(1);//工单类型：1开单单 2拆单单 3移交单 4生产单 5回收单 6出货单 7补单单 8合并单...
				workingOrder.setCount(vo.getCount());//存货数量
				workingOrder.setStoreBy(storeBy);//存货人
				workingOrder.setStoreDept(storeDept);//存货部门
				workingOrder.setStoreStatus(1);//工单存货状态：1存货、2报废、3交货
				workingOrder.setPid("0");//根节点
				isSuc = workingOrderService.save(workingOrder);//保存生产开单数据
				isSuc = cusStyleInfoService.openWorkOrder(vo.getCusStyleId());//设置订单的开工单状态
				if(receiveBy != null && !"".equals(receiveBy)) {//当设置了移交接收人的时候，需要发送站内通知，提醒接收人
					WorkingOrderRecord workingOrderRecord = new WorkingOrderRecord();
					workingOrderRecord.setCount(vo.getCount());//数量
					workingOrderRecord.setParentId("0");//默认是根节点
					workingOrderRecord.setWorkOrderType(1);//工单类型：1开单单 2拆单单 3移交单 4生产单 5回收单 6出货单 7补单单 8合并单...
					workingOrderRecord.setPn(pn);//拆分页
					workingOrderRecord.setWorkNum(workNum);//工单号
					workingOrderRecord.setSendBy(sendBy);//发送人
					workingOrderRecord.setSendDept(sendDept);//发送部门
					workingOrderRecord.setSendTime(nowTime);//发送时间
					workingOrderRecord.setReceiveBy(receiveBy);//接收人
					workingOrderRecord.setReceiveDept(receiveDept);//接收部门
					workingOrderRecord.setReceiveTime(nowTime);//接收时间
					workingOrderRecord.setWorkingOrderId(workingOrder.getId());//工单ID
					workingOrderRecordService.addWorkingOrderRecord(workingOrderRecord);//保存移交记录
					
					WorkingOrder updateWorkingOrder = new WorkingOrder();
					updateWorkingOrder.setId(workingOrder.getId());
					updateWorkingOrder.setCurrWorkingOrderRecordId(workingOrderRecord.getId());
					workingOrderService.updateById(updateWorkingOrder);
					try {//发送站内消息提醒
						SysUser receiveUser = sysUserService.getUserByName(receiveBy);
						SysAnnouncementController announcementController = (SysAnnouncementController) SpringContextUtils.getBean(SysAnnouncementController.class);
						String title = "生产开单通知"+"(工单号："+workNum +")";
						String msgContent = "工单号："+workNum +"，数量："+workingOrder.getCount()+"，请安排生产计划。详情登录查看生产跟单系统。";
						announcementController.addAndSend(title, msgContent, 1, receiveUser.getId()+",");
					} catch (ParseException e) {
						e.printStackTrace();
						isSuc = false;
					}
				}
			}
			if(isSuc) {
				CusOrderInfo cusOrderInfo = cusOrderInfoService.getById(orderInfoId);
				//订单状态。0暂存草稿、1待审单、-1审单不通过、2待转生产单、3待开工单、10做货中、11部分做货完成、12全部做货完成、20部分出货、21全部出货
				if(cusOrderInfo.getStatus() == 3) {//订单仍是待开工单状态。
					int allOrderStyleCount = cusOrderInfoMapper.countAllOrderStyle(orderInfoId);
					int openedStyleCount = cusOrderInfoMapper.countOpenedOrderStyle(orderInfoId);
					if(openedStyleCount == allOrderStyleCount) {
						//订单状态：0暂存草稿、1待审单、-1审单不通过、2待转生产单、3待开工单、10做货中、11部分做货完成、12全部做货完成、20部分出货、21全部出货
						//如果该订单下的款式都已开工单，则更新订单状态为：10做货中
						cusOrderInfoService.updateStatus(orderInfoId, 10);
					}
				}
			}
		}
		return isSuc ? Result.ok("开工单成功！") : Result.error("开工单失败！");
	}
	
	
	/**
	 * 通过订单id获取下一拆分页的字符串
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "通过订单id获取下一拆分页")
	@ApiOperation(value="通过订单id获取下一拆分页", notes="通过订单id获取下一拆分页")
	@GetMapping(value = "/getNextStartPn")
	public Result<?> getNextStartPn(@RequestParam(name="orderInfoId",required=true) String orderInfoId) {
		String nextStartPn = workingOrderService.getNextStartPn(orderInfoId);
		return Result.OK(nextStartPn);
	}
	
	/**
	 *  拆子工单
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "生产工单-拆子工单")
	@ApiOperation(value="生产工单-拆子工单", notes="生产工单-拆子工单")
	@PostMapping(value = "/splitChild")
	@Transactional
	public Result<?> splitChild(@RequestBody JSONObject params) {
		Date nowTime = new Date();
		Integer countRemain = params.getInteger("count");//剩余数量
		Integer countSplit = params.getInteger("takeCount");//拆出的数量
		String withStoneWeight = params.getString("withStoneWeight");//拆出的连石重
		BigDecimal withStoneWeightVal = (withStoneWeight == null || "".equals(withStoneWeight)) ? new BigDecimal("0") : new BigDecimal(withStoneWeight);
		System.out.println("countRemain======="+countRemain+"=====countSplit==="+countSplit+"====withStoneWeight==="+withStoneWeight);
		String pid = params.getString("pid");//父工单ID
		WorkingOrder parentOrder = this.workingOrderService.getById(pid);
		CusStyleInfo cusStyleInfo = this.cusStyleInfoService.getById(parentOrder.getStyleCusInfoId());//款式信息
		String orderInfoId = parentOrder.getOrderInfoId();//订单ID
		if(countSplit <= 0) {
			Result.error("拆分数量不能为0！");
		}
		if(countSplit > parentOrder.getCount()) {
			Result.error("拆分数量不能超过可拆数量("+parentOrder.getCount()+")！");
		}
		boolean isSuc = false;
		WorkingOrderRecord parentWorkingOrderRecord = this.workingOrderRecordService.getById(parentOrder.getCurrWorkingOrderRecordId());
		BigDecimal pureStoneWeightOrig = parentWorkingOrderRecord.getPureStoneWeight();//原石重
		BigDecimal withStoneWeightOrig = parentWorkingOrderRecord.getPureStoneWeight();//原连石重
		withStoneWeightOrig = withStoneWeightOrig == null ? new BigDecimal("0") : withStoneWeightOrig;
		BigDecimal pureStoneWeightSplit = new BigDecimal("0");//拆出的石重
		if(pureStoneWeightOrig != null) {
			pureStoneWeightSplit =  (new BigDecimal(countSplit).divide(new BigDecimal(parentOrder.getCount()),2, BigDecimal.ROUND_HALF_UP)).multiply(pureStoneWeightOrig);
		}else {
			pureStoneWeightOrig = new BigDecimal("0");
		}
		String currMaxPnString = workingOrderMapper.getMaxPnByOrderInfoId(orderInfoId);//当前工单的最大拆分页
		String newPn = getPn(Integer.parseInt(currMaxPnString) + 1);//新的拆分页开始：当前最大拆分页+1
		
		WorkingOrder workingOrder = new WorkingOrder();
		workingOrder.setPn(newPn);// 拆分页
		workingOrder.setWorkNum(parentOrder.getWorkNum());// 拆出来的工单号必须与父工单号相同
		workingOrder.setStyleCodeNum(cusStyleInfo.getCodeNum());//款号
		workingOrder.setStyleImageString(cusStyleInfo.getStyleImageString());//图片
		workingOrder.setOrderInfoId(orderInfoId);// 订单ID
		workingOrder.setStyleCusInfoId(cusStyleInfo.getId());// 款式ID
		workingOrder.setWorkOrderType(2);// 工单类型：1开单单 2拆单单 3回收单 4补单单 5合并单
		workingOrder.setCount(countSplit);// 存货数量
		workingOrder.setStoreBy(parentOrder.getStoreBy());// 存货人
		workingOrder.setStoreDept(parentOrder.getStoreDept());// 存货部门
		workingOrder.setStoreStatus(1);// 工单存货状态：1存货、2报废、3交货
		workingOrder.setPid(pid);// 根节点
		isSuc = workingOrderService.save(workingOrder);
		

		WorkingOrderRecord workingOrderRecord = new WorkingOrderRecord();
		workingOrderRecord.setCount(countSplit);// 数量
		workingOrderRecord.setParentId("0");// 默认是根节点
		workingOrderRecord.setWorkOrderType(2);// 工单类型：1开单单 2拆单单 3移交单 4生产单 5回收单 6出货单 7补单单 8合并单...
		workingOrderRecord.setPn(newPn);// 拆分页
		workingOrderRecord.setWorkNum(parentOrder.getWorkNum());// 工单号
		workingOrderRecord.setSendBy(parentOrder.getStoreBy());// 发送人
		workingOrderRecord.setSendDept(parentOrder.getStoreDept());// 发送部门
		workingOrderRecord.setSendTime(nowTime);// 发送时间
		workingOrderRecord.setReceiveBy(parentOrder.getStoreBy());// 接收人
		workingOrderRecord.setReceiveDept(parentOrder.getStoreDept());// 接收部门
		workingOrderRecord.setReceiveTime(nowTime);// 接收时间
		workingOrderRecord.setWorkingOrderId(workingOrder.getId());// 工单ID
		workingOrderRecord.setWithStoneWeight(formatBigDecimal(withStoneWeightVal));//拆出的连石重
		workingOrderRecord.setPureStoneWeight(formatBigDecimal(pureStoneWeightSplit));//拆出的石重(ct) 1ct = 0.2g
		workingOrderRecord.setGoldWeight(formatBigDecimal(withStoneWeightVal.subtract(pureStoneWeightSplit.multiply(new BigDecimal("0.2")))));//拆出的净金重
		workingOrderRecord.setStoreStatus(parentOrder.getStoreStatus());
		isSuc = workingOrderRecordService.addWorkingOrderRecord(workingOrderRecord);// 写入数据库，保存数据

		WorkingOrder updateWorkingOrder = new WorkingOrder();
		updateWorkingOrder.setId(workingOrder.getId());
		updateWorkingOrder.setCurrWorkingOrderRecordId(workingOrderRecord.getId());
		isSuc = workingOrderService.updateById(updateWorkingOrder);// 写入数据库，保存数据

		if(isSuc) {
			/**剩余可拆数量要更新工单信息，并新增一条生产过程记录*/
			BigDecimal pureStoneWeightRemain = new BigDecimal("0");//剩余石重
			WorkingOrderRecord record = new WorkingOrderRecord();
			record.setCount(countRemain);//数量
			record.setParentId("0");//默认是根节点
			record.setWorkOrderType(2);//工单类型：1开单单 2拆单单 3移交单 4生产单 5回收单 6出货单 7补单单 8合并单...
			record.setPn(parentOrder.getPn());//拆分页
			record.setWorkNum(parentOrder.getWorkNum());//工单号
			record.setSendBy(parentOrder.getStoreBy());// 发送人
			record.setSendDept(parentOrder.getStoreDept());// 发送部门
			record.setSendTime(nowTime);// 发送时间
			record.setReceiveBy(parentOrder.getStoreBy());// 接收人
			record.setReceiveDept(parentOrder.getStoreDept());// 接收部门
			record.setReceiveTime(nowTime);// 接收时间
			record.setWorkingOrderId(parentOrder.getId());// 工单ID
			if(pureStoneWeightOrig.compareTo(BigDecimal.ZERO) != 0) {
				pureStoneWeightRemain = pureStoneWeightOrig.subtract(pureStoneWeightSplit);//剩余石重=原石重-拆出的石重
				record.setPureStoneWeight(formatBigDecimal(pureStoneWeightRemain));//剩余石重
			}
			BigDecimal withStoneWeightRemain = withStoneWeightOrig.subtract(withStoneWeightVal);//剩余连石重=原连石重-拆出的连石重
			record.setWithStoneWeight(formatBigDecimal(withStoneWeightRemain));//剩余连石重
			record.setGoldWeight(formatBigDecimal(withStoneWeightRemain.subtract(pureStoneWeightRemain.multiply(new BigDecimal("0.2")))));//剩余净金重
			record.setStoreStatus(parentOrder.getStoreStatus());
			isSuc = workingOrderRecordService.addWorkingOrderRecord(record);// 写入数据库，保存数据
			
			WorkingOrder updWorkingOrder = new WorkingOrder();
			updWorkingOrder.setId(parentOrder.getId());
			updWorkingOrder.setWorkOrderType(2);//更新为拆单单
			updWorkingOrder.setCount(parentOrder.getCount() - countSplit);//剩余可拆数量
			updWorkingOrder.setHasChild("1");
			updWorkingOrder.setIsSplited(1);
			updWorkingOrder.setCurrWorkingOrderRecordId(record.getId());
			isSuc = workingOrderService.updateById(updWorkingOrder);// 写入数据库，保存数据
			
			UpdateWrapper<WorkingOrderRecord>  updPparentWorkingOrderRecord = new UpdateWrapper<>();
			updPparentWorkingOrderRecord.set("store_status", null);
			
			updPparentWorkingOrderRecord.eq("id", parentWorkingOrderRecord.getId());
			isSuc = workingOrderRecordService.update(updPparentWorkingOrderRecord);
		}
		if(!isSuc) {
			throw new RuntimeException("拆工单失败！");
		}
		return  Result.ok("成功拆分工单为"+parentOrder.getPn()+","+newPn+"！");
	}
	
	
	/**
	 *  拆子工单
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "生产工单-拆子工单")
	@ApiOperation(value="生产工单-拆子工单", notes="生产工单-拆子工单")
	@PostMapping(value = "/splitChild_Bak20211108")
	@Transactional
	public Result<?> splitChild_Bak20211108(@RequestBody JSONObject params) {
		LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		Date nowTime = new Date();
		Integer count = params.getInteger("count");//剩余可拆数量
		Integer takeCount = params.getInteger("takeCount");//拆分数量
		Integer every = params.getInteger("every");//每页数量
		String pid = params.getString("pid");//父工单ID
		WorkingOrder parentOrder = this.workingOrderService.getById(pid);
		String styleCusInfoId = parentOrder.getStyleCusInfoId();//款式ID
		String orderInfoId = parentOrder.getOrderInfoId();//订单ID
		if(takeCount <= 0) {
			Result.error("拆分数量不能为0！");
		}
		if(takeCount > parentOrder.getCount()) {
			Result.error("拆分数量不能超过可拆数量("+parentOrder.getCount()+")！");
		}
		Integer pnCount = Math.floorDiv(takeCount, every);//按照平均法，计算可拆页数
		Integer sub = takeCount - pnCount * every;//平均法计算后，还剩余多少件无法整除
		boolean isSuc = false;
		String currMaxPnString = workingOrderMapper.getMaxPnByOrderInfoId(orderInfoId);//当前工单的最大拆分页
		Integer start = Integer.parseInt(currMaxPnString) + 1;//新的拆分页开始：当前最大拆分页+1
		Integer end = Integer.parseInt(currMaxPnString) + pnCount;//新的拆分页结束：当前最大拆分页+可拆页数
		int k = 0 ;
		String str = "";
		for(int i=start;i<=end;i++) {
			k++;
			int everyCount = every;
			if( i == end && sub > 0) {//平均法拆分后，还有剩余件数，则最后一页的件数要加上剩余件数
				everyCount += sub;
			}
			String pn = this.getPn(i);//拆分序号
			if(i == start) {
				str +=","+pn+",...";
			} else if(i == end) {
				str +=","+pn;
			}
			
			WorkingOrder workingOrder = new WorkingOrder();
			workingOrder.setPn(pn);//拆分页
			workingOrder.setWorkNum(parentOrder.getWorkNum());//拆出来的工单号必须与父工单号相同
			workingOrder.setOrderInfoId(orderInfoId);//订单ID
			workingOrder.setStyleCusInfoId(styleCusInfoId);//款式ID
			workingOrder.setWorkOrderType(2);//工单类型：1开单单 2拆单单 3回收单 4补单单 5合并单
			workingOrder.setCount(everyCount);//存货数量
			workingOrder.setStoreBy(loginUser.getUsername());//存货人
			workingOrder.setStoreDept(loginUser.getOrgCode());//存货部门
			workingOrder.setStoreStatus(1);//工单存货状态：1存货、2报废、3交货
			workingOrder.setPid(pid);//根节点
			isSuc = workingOrderService.save(workingOrder);
			
			
			WorkingOrderRecord workingOrderRecord = new WorkingOrderRecord();
			workingOrderRecord.setCount(everyCount);//数量
			workingOrderRecord.setParentId("0");//默认是根节点
			workingOrderRecord.setWorkOrderType(2);//工单类型：1开单单 2拆单单 3移交单 4生产单 5回收单 6出货单 7补单单 8合并单...
			workingOrderRecord.setPn(pn);//拆分页
			workingOrderRecord.setWorkNum(parentOrder.getWorkNum());//工单号
			workingOrderRecord.setSendBy(loginUser.getUsername());// 发送人
			workingOrderRecord.setSendDept(loginUser.getOrgCode());// 发送部门
			workingOrderRecord.setSendTime(nowTime);// 发送时间
			workingOrderRecord.setReceiveBy(loginUser.getUsername());// 接收人
			workingOrderRecord.setReceiveDept(loginUser.getOrgCode());// 接收部门
			workingOrderRecord.setReceiveTime(nowTime);// 接收时间
			workingOrderRecord.setWorkingOrderId(workingOrder.getId());// 工单ID
			isSuc = workingOrderRecordService.addWorkingOrderRecord(workingOrderRecord);// 写入数据库，保存数据
			
			WorkingOrder updateWorkingOrder = new WorkingOrder();
			updateWorkingOrder.setCurrWorkingOrderRecordId(workingOrderRecord.getId());
			updateWorkingOrder.setId(workingOrder.getId());
			isSuc = workingOrderService.updateById(updateWorkingOrder);// 写入数据库，保存数据
		}
		if(isSuc) {
			/**剩余可拆数量要生成一条工单信息：新工单的拆分页码必须和被拆工单的页码相同。*/
			WorkingOrder workingOrder = new WorkingOrder();
			workingOrder.setPn(parentOrder.getPn());
			workingOrder.setWorkNum(parentOrder.getWorkNum());
			workingOrder.setOrderInfoId(orderInfoId);
			workingOrder.setStyleCusInfoId(styleCusInfoId);
			workingOrder.setWorkOrderType(2);//工单类型：1开单单 2拆单单 3回收单 4补单单 5合并单
			workingOrder.setCount(count);//剩余可拆数量
			workingOrder.setStoreBy(loginUser.getUsername());//存货人
			workingOrder.setStoreDept(loginUser.getOrgCode());//存货部门
			workingOrder.setStoreStatus(1);//工单存货状态：1存货、2报废、3交货
			workingOrder.setPid(pid);//根节点
			isSuc = workingOrderService.save(workingOrder);// 写入数据库，保存数据
			
			WorkingOrderRecord workingOrderRecord = new WorkingOrderRecord();
			workingOrderRecord.setCount(count);//数量
			workingOrderRecord.setParentId("0");//默认是根节点
			workingOrderRecord.setWorkOrderType(2);//工单类型：1开单单 2拆单单 3移交单 4生产单 5回收单 6出货单 7补单单 8合并单...
			workingOrderRecord.setPn(parentOrder.getPn());//拆分页
			workingOrderRecord.setWorkNum(parentOrder.getWorkNum());//工单号
			workingOrderRecord.setSendBy(loginUser.getUsername());// 发送人
			workingOrderRecord.setSendDept(loginUser.getOrgCode());// 发送部门
			workingOrderRecord.setSendTime(nowTime);// 发送时间
			workingOrderRecord.setReceiveBy(loginUser.getUsername());// 接收人
			workingOrderRecord.setReceiveDept(loginUser.getOrgCode());// 接收部门
			workingOrderRecord.setReceiveTime(nowTime);// 接收时间
			workingOrderRecord.setWorkingOrderId(workingOrder.getId());// 工单ID
			isSuc = workingOrderRecordService.addWorkingOrderRecord(workingOrderRecord);// 写入数据库，保存数据
			
			WorkingOrder updateWorkingOrder = new WorkingOrder();
			updateWorkingOrder.setId(workingOrder.getId());
			updateWorkingOrder.setCurrWorkingOrderRecordId(workingOrderRecord.getId());
			isSuc = workingOrderService.updateById(updateWorkingOrder);// 写入数据库，保存数据
			
			
			UpdateWrapper<WorkingOrder> updateWrapper = new UpdateWrapper<>();
			updateWrapper.set("has_child", "1");
			updateWrapper.set("is_splited", "1");
			updateWrapper.set("store_status",null);
			updateWrapper.eq("id", pid);
			isSuc = workingOrderService.update(updateWrapper);
			
		}
		if(!"".equals(str)) {
			str = str.substring(1);
		}
		if(!isSuc) {
			throw new RuntimeException("拆工单失败！");
		}
		return  Result.ok("成功拆分"+k+"张工单（"+str+"）！");
	}
	
	/**
	 *  合并工单
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "生产工单-合并工单")
	@ApiOperation(value="生产工单-合并工单", notes="生产工单-合并工单")
	@DeleteMapping(value = "/merge")
	public Result<?> merge(@RequestParam(name="ids",required=true) String ids) {
		LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		List<String> idsList = Arrays.asList(ids.split(","));
		String storeBy = "";//存货人
		Integer i = 0;//执行工单合并操作的成功条数
		if(!idsList.isEmpty()) {
			int row = 0;
			for(String id : idsList) {
				row++;
				WorkingOrder workOrder = this.workingOrderService.getById(id);
				//if(workOrder.getWorkOrderType() == 1) {//如果是开单单，则不允许合并
				//	return Result.error("合并的工单不能包含开单单！");
				//}
				if(row == 1) {
					storeBy = StringUtils.trimToEmpty(workOrder.getStoreBy());
				} else {
					if(!storeBy.equals(StringUtils.trimToEmpty(workOrder.getStoreBy()))) {
						return Result.error("合并的工单需在同一存货人手上！");
					}
				}
			}
			Result<?> result =  this.workingOrderService.mergeByIds(idsList,loginUser);
			return result;
		}
		return Result.ok("（"+i+"）条工单合并成功！");
	}
	
	/**
	 *  交收
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "生产工单-交收")
	@ApiOperation(value="生产工单-交收", notes="生产工单-交收")
	@PostMapping(value = "/settlement")
	@Transactional
	public Result<?> settlement(@RequestBody JSONObject jsonObject) {
		LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		String sendBy = loginUser.getUsername();//当前登录用户的用户名
		String sendDept = this.sysDepartService.queryUserDeparts(loginUser.getId()).get(0).getId();//根据用户ID查出所属部门
		Date now = new Date();//当前时间
		String workNo = jsonObject.getString("workNo");//工号
		String receiveBy = sysUserService.getUsernameByWorkNo(workNo);//根据工号查出用户名
		if(receiveBy != null) {
			WorkingOrderRecord workingOrderRecord = new WorkingOrderRecord();
			String receiveDept = this.sysDepartService.queryDepartsByUsername(receiveBy).get(0).getId();//根据接收人的用户名查出接收人的所属部门
			if(this.WORKDER_ORDER_CONFIRM_MODE == 1) {//当系统采用员工打卡确认模式的时候，要更新接收时间
				workingOrderRecord.setReceiveTime(now);//接收时间
			}
			workingOrderRecord.setSendBy(sendBy);//发送人
			workingOrderRecord.setSendDept(sendDept);//发送部门
			workingOrderRecord.setSendTime(now);//发送时间
			workingOrderRecord.setReceiveBy(receiveBy);//接收人
			workingOrderRecord.setReceiveDept(receiveDept);//接收部门
			workingOrderRecord.setCount(jsonObject.getInteger("count"));//数量
			workingOrderRecord.setNoAttritionWeight(jsonObject.getBigDecimal("noAttritionWeight"));//不计耗重
			workingOrderRecord.setGoldWeight(jsonObject.getBigDecimal("goldWeight"));//净金重
			workingOrderRecord.setSilverModelWeight(jsonObject.getBigDecimal("silverModelWeight"));//净银重
			workingOrderRecord.setWaxModelWeight(jsonObject.getBigDecimal("waxModelWeight"));//蜡重
			workingOrderRecord.setPureStoneWeight(jsonObject.getBigDecimal("pureStoneWeight"));//石重
			workingOrderRecord.setWithStoneWeight(jsonObject.getBigDecimal("withStoneWeight"));//连石重
			workingOrderRecord.setOtherAccessoryWeight(jsonObject.getBigDecimal("otherAccessoryWeight"));//其他配件重
			workingOrderRecord.setAccessoryCount(jsonObject.getInteger("accessoryCount"));//配件数
			workingOrderRecord.setOriginalWeight(jsonObject.getBigDecimal("originalWeight"));//原重量
			workingOrderRecord.setDifference(jsonObject.getBigDecimal("difference"));//差额
			workingOrderRecord.setAttritionRate(jsonObject.getBigDecimal("attritionRate"));//耗率
			workingOrderRecord.setGate(jsonObject.getBigDecimal("gate"));//水口或链尾
			workingOrderRecord.setGiveAttrition(jsonObject.getBigDecimal("giveAttrition"));//给耗
			workingOrderRecord.setRemark(jsonObject.getString("remark"));//备注
			workingOrderRecord.setWorkNum(jsonObject.getString("workNum"));//工单号
			workingOrderRecord.setWorkingOrderId(jsonObject.getString("workingOrderId"));//工单ID
			workingOrderRecord.setPn(jsonObject.getString("pn"));//拆分页
			workingOrderRecordService.addWorkingOrderRecord(workingOrderRecord);
			
			WorkingOrder workingOrder = new WorkingOrder();//更新工单数据
			workingOrder.setId(workingOrderRecord.getWorkingOrderId());
			workingOrder.setCurrWorkingOrderRecordId(workingOrderRecord.getId());//更新工单当前的做货记录ID
			workingOrder.setStoreBy(receiveBy);//设置新的存货人
			workingOrder.setStoreStatus(1);//存货状态为：1存货。（1存货、2交货、3报废）
			workingOrder.setStoreDept(receiveDept);//设置新的存货部门
			this.workingOrderService.updateById(workingOrder);//更新主表数据
		}
		return Result.OK("操作成功！");
	}
	
	/**
	 * 获取拆分序号
	 * @param pn
	 * @return
	 */
	private String getPn(Integer pn) {
		if(pn < 10) {
			return "0"+String.valueOf(pn);
		} else {
			return String.valueOf(pn);
		}
	}
	
	/**
	 * 为BigDecimal赋值
	 * @param pn
	 * @return
	 */
	private BigDecimal formatBigDecimal(BigDecimal value) {
		if(value == null || value.compareTo(BigDecimal.ZERO) == 0) {
			return null;
		}
		return value;
	}

    /**
    * 导出excel
    *
    * @param request
    * @param productionOrderInfo
    */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, WorkingOrder workingOrder) {
		return super.exportXls(request, workingOrder, WorkingOrder.class, "生产工单");
    }

    /**
      * 通过excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
		return super.importExcel(request, response, WorkingOrder.class);
    }

}
